const mongoose = require('mongoose');

/**
 * 用户模型
 * 存储用户基本信息、认证信息和令牌
 * 前端负责数据验证，后端只保留必要的安全验证
 */
const userSchema = new mongoose.Schema({
  // 用户邮箱，作为唯一标识和登录凭证
  email: {
    type: String,
    required: true,
    unique: true
  },

  // 用户密码
  password: {
    type: String,
    required: true
  },

  // 商户名称，唯一标识
  username: {
    type: String,
    required: true,
    unique: true
  },

  // 邮箱验证码，用于注册和重置密码
  verificationCode: {
    type: String,
    select: false  // 查询时默认不返回验证码，增加安全性
  },

  // 验证码过期时间
  codeExpires: {
    type: Date,
    select: false
  },

  // 邮箱是否已验证
  isVerified: {
    type: Boolean,
    default: false  // 默认未验证
  },

  // 用户角色，RBAC权限控制
  roles: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Role'
  }],

  // 账号状态
  status: {
    type: String,
    enum: ['正常', '冻结', '待审核'],
    default: '待审核'
  },

  // 商家ID，如 'M25001'
  merchantId: {
    type: String,
    sparse: true  // 允许为空，但如果有值则必须唯一
  },

  // 注册日期
  registrationDate: {
    type: Date,
    default: Date.now
  }
}, {
  timestamps: true  // 自动添加createdAt和updatedAt字段
});


/**
 * 实例方法：验证密码
 */
userSchema.methods.matchPassword = function (enteredPassword) {
  // 直接比较密码
  return this.password === enteredPassword;
};

/**
 * 实例方法：检查用户是否有指定权限
 */
userSchema.methods.hasPermission = async function (permissionCode) {
  // 获取用户的所有角色及其权限
  const populatedUser = await this.constructor.findById(this._id)
    .populate({
      path: 'roles',
      populate: {
        path: 'permissions'
      }
    });

  // 检查用户的所有角色中是否有包含指定权限的角色
  for (const role of populatedUser.roles) {
    for (const permission of role.permissions) {
      if (permission.code === permissionCode) {
        return true;
      }
    }
  }

  return false;
};







/**
 * 实例方法：获取用户所有权限
 */
userSchema.methods.getAllPermissions = async function () {
  // 获取用户的所有角色及其权限
  const populatedUser = await this.constructor.findById(this._id)
    .populate({
      path: 'roles',
      populate: {
        path: 'permissions'
      }
    });

  // 使用Set去重，收集所有权限
  const permissionsSet = new Set();

  for (const role of populatedUser.roles) {
    for (const permission of role.permissions) {
      permissionsSet.add(permission.code);
    }
  }

  return Array.from(permissionsSet);
};

const User = mongoose.model('User', userSchema);

module.exports = User; 